package ija.net;

import ija.controller.CheckersController;
import ija.controller.CheckersController.AskForConnection;
import ija.controller.CheckersController.LoadGame;
import ija.controller.CheckersController.StartGame;
import ija.model.basis.Desk;
import ija.model.basis.Position;
import ija.model.figures.Piece;
import ija.model.figures.Queen;
import ija.model.types.FigureColor;
import ija.xls.xml.game.FigureDescription;
import ija.xls.xml.game.FigureDescription.FigureType;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.util.Iterator;
import org.dom4j.DocumentException;

/**
 * Trida zajistuje sitovou komunikaci pro hru dama. Predstavuje pasivni cast
 * peer-to-peer komunikace.
 * 
 * @author Radek Necas, xnecas18
 */
public class Listener extends Networker {

	Desk initDesk;

	/**
	 * Konstruktor pro Listener.
	 * 
	 * @param controller
	 */
	public Listener(CheckersController controller) {
		super(controller);
		this.initDesk = null;
	}

	/**
	 * Metoda inicializuje Listener.
	 * 
	 * @param port
	 *            port na kterem bude naslouchat server.
	 * @throws IOException
	 */
	public void init(int port) throws IOException {
		this.server = new Server(port, this);
		this.server.start();
	}

	public Desk getInitDesk() {
		return this.initDesk;
	}

        
        ////////////////////////////////////////////////////////////////////////////
        //////////////////// ZASILANI ZPRAV ////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
        // region SEND MESSAGE
        
        
        public void sendConfirm(boolean checked) throws IOException {
            if(client == null) {
                throw new IOException("Client not created");
            }
        
            client.send(new Message(MessageType.CONFIRM, String.valueOf(checked)));
        }
        
        
        // endregion SEND MESSAGE
        
	// //////////////////////////////////////////////////////////////////////////
	// //////////////// ZPRACOVANI UDALOSTI OD SERVERU //////////////////////////
	// //////////////////////////////////////////////////////////////////////////
	// region SERVE MESSAGE

	/**
	 * Metoda zpracovava udalosti od serveru, ktere jsou specificke pouze pro
	 * Listener. Ostatni preposila nadtrite Networker.
	 * 
	 * @param msg
	 */
	@Override
	public void serveMessage(Message msg) {
		switch (msg.type) {
		case ASKFORCONN:
			// Zobrazi parametry uzivateli, a az pokud to uzivatel odsouhlasi
			// zasle se accept - NEBUDE SE ZASILAT TADY!!!!!
			this.fireAskForConn(msg);
			break;

		case DESKINFO:
			this.fireDeskInfo(msg);
			break;

		case STARTGAME:
			this.fireStartGame(msg);
			break;

		default:
			super.serveMessage(msg);
		}
	}

	/**
	 * Preposlani ASKFORCONN kontroleru
	 * 
	 * @param msg
	 */
	protected void fireAskForConn(Message msg) {
		/*
		 * String[] host = msg.getDetails().split(":"); if (host.length != 2) {
		 * System.err.println("Chyba v parsovani adresy"); }
		 * 
		 * // Ip a port bych mel zaslat kontroleru String ip = host[0]; int port
		 * = Integer.valueOf(host[1]);
		 */
		AskForConnection ask = this.controller.createAskForConnListener();
		ask.ActionPerformed(new ActionEvent(this, 0, msg.getDetails()));

		/*
		 * // Tato cast by se mela provest v metode, kterou bude volat //
		 * kontroler try { client = new Client(ip, port); } catch
		 * (UnknownHostException ex) {
		 * System.err.println("Listener neprelozil ip: " +
		 * ex.getLocalizedMessage()); } try { super.sendAccept(); } catch
		 * (IOException ex) { System.err.println("Nepodarilo se zaslat accept: "
		 * + ex.getLocalizedMessage()); }
		 */

	}

	protected void fireDeskInfo(Message msg) {
                System.out.println("Listener fireDeskInfo");
		try {
			this.xml.initInputFromString(msg.getDetails());
		} catch (DocumentException ex) {
			System.err.println("Chybny format zpravy DESKINFO");
		}

		this.initDesk = new Desk();
		for (int i = 0; i < 2; i++) {
			FigureColor fc;
			fc = (i == 0 ? FigureColor.BLACK : FigureColor.WHITE);
			Iterator<FigureDescription> figs = this.xml.figuresIterator(fc);
			FigureDescription fd;
			Position p;
			while (figs.hasNext()) {
				fd = figs.next();
                                p = this.initDesk.getPositionAt(fd.getCoordinate());
				if (fd.getFigureType() == FigureType.QUEEN) {
					Queen q = new Queen(p, fd.getColor());
					p.putFigure(q);
				} else if (fd.getFigureType() == FigureType.PIECE) {
					Piece piece = new Piece(p, fd.getColor(), fd.getDirection());
					p.putFigure(piece);
				}
			}
		}

		this.xml.clearInput();

                System.out.println("Listener vytvoril desku:");
                initDesk.printOccupy();
		LoadGame loadGameListener = this.controller.createLoadGameListener();
		loadGameListener.actionPerformed(new ActionEvent(this, 0, null));
	}

	protected void fireStartGame(Message msg) {
		StartGame startGameListener = this.controller.createStartGameListener();
		startGameListener.actionPerformed(new ActionEvent(this, 0, null));
	}

	// endregion SERVE MESSAGE
}
